Disable PL011 UART before configuring it
authorJuan Castillo <[email protected]>
Thu, 26 Nov 2015 14:52:15 +0000 (14:52 +0000)
committerJuan Castillo <[email protected]>
Thu, 21 Jan 2016 17:27:47 +0000 (17:27 +0000)
The PL011 TRM (ARM DDI 0183G) specifies that the UART must be
disabled before any of the control registers are programmed. The
PL011 driver included in TF does not disable the UART, so the
initialization in BL2 and BL31 is violating this requirement
(and potentially in BL1 if the UART is enabled after reset).

This patch modifies the initialization function in the PL011
console driver to disable the UART before programming the
control registers.

Register clobber list and documentation updated.

Fixes ARM-software/tf-issues#300

Change-Id: I839b2d681d48b03f821ac53663a6a78e8b30a1a1

docs/porting-guide.md
drivers/arm/pl011/pl011_console.S
drivers/console/console.S
include/drivers/arm/pl011.h
plat/arm/common/aarch64/arm_helpers.S
plat/mediatek/mt8173/aarch64/plat_helpers.S
plat/nvidia/tegra/common/aarch64/tegra_helpers.S

index cdb722afd3022e987c290349e9c57d910b2da264..66d41219db04fd0f231f4ea5f2b9bc9b12f20352 100644 (file)
@@ -1860,7 +1860,7 @@ they can be invoked without a C Runtime stack.
     Return   : int
 
 This API is used by the crash reporting mechanism to initialize the crash
-console. It should only use the general purpose registers x0 to x2 to do the
+console. It must only use the general purpose registers x0 to x4 to do the
 initialization and returns 1 on success.
 
 ### Function : plat_crash_console_putc
@@ -1869,7 +1869,7 @@ initialization and returns 1 on success.
     Return   : int
 
 This API is used by the crash reporting mechanism to print a character on the
-designated crash console. It should only use general purpose registers x1 and
+designated crash console. It must only use general purpose registers x1 and
 x2 to do its work. The parameter and the return value are in general purpose
 register x0.
 
index 47608da31586a6113fa6474435eab9b7ae1ad223..f29f895b595c20b0b86479513c8a4a6b5161706e 100644 (file)
@@ -54,7 +54,7 @@
         *     w1 - Uart clock in Hz
         *     w2 - Baud rate
         * Out: return 1 on success else 0 on error
-        * Clobber list : x1, x2
+        * Clobber list : x1, x2, x3, x4
         * -----------------------------------------------
         */
 func console_core_init
@@ -64,6 +64,20 @@ func console_core_init
        /* Check baud rate and uart clock for sanity */
        cbz     w1, core_init_fail
        cbz     w2, core_init_fail
+       /* Disable uart before programming */
+       ldr     w3, [x0, #UARTCR]
+       mov     w4, #PL011_UARTCR_UARTEN
+       bic     w3, w3, w4
+       str     w3, [x0, #UARTCR]
+       /* Flush the transmit FIFO */
+       ldr     w3, [x0, #UARTLCR_H]
+       mov     w4, #PL011_UARTLCR_H_FEN
+       bic     w3, w3, w4
+       str     w3, [x0, #UARTLCR_H]
+       /* Wait for the end of Tx of current character */
+busy_loop:
+       ldr     w3, [x0, #UARTFR]
+       tbnz    w3, #PL011_UARTFR_BUSY_BIT, busy_loop
        /* Program the baudrate */
        /* Divisor =  (Uart clock * 4) / baudrate */
        lsl     w1, w1, #2
index b7723638e3fe751268ee4a2b98aeb2ea271d6b62..797b56450d18a7f21c73110e11032f734c68b147 100644 (file)
@@ -54,7 +54,7 @@
         *     w1 - Uart clock in Hz
         *     w2 - Baud rate
         * out: return 1 on success else 0 on error
-        * Clobber list : x1 - x3
+        * Clobber list : x1 - x4
         * -----------------------------------------------
         */
 func console_init
index d5ea890defff4c0e05a175b610e63593eed42a09..ce6cdcf56935b3a3a30f997ae4b84b778f909522 100644 (file)
@@ -71,6 +71,7 @@
 
 #define PL011_UARTFR_TXFF_BIT  5       /* Transmit FIFO full bit in UARTFR register */
 #define PL011_UARTFR_RXFE_BIT  4       /* Receive FIFO empty bit in UARTFR register */
+#define PL011_UARTFR_BUSY_BIT  3       /* UART busy bit in UARTFR register */
 
 /* Control reg bits */
 #if !PL011_GENERIC_UART
index 87179daeadf4751d103e9deadb829279ecdc2038..a0338f165c90d64b2558ab95d639feb1e3d4121c 100644 (file)
@@ -66,7 +66,7 @@ endfunc plat_arm_calc_core_pos
         * int plat_crash_console_init(void)
         * Function to initialize the crash console
         * without a C Runtime to print crash report.
-        * Clobber list : x0, x1, x2
+        * Clobber list : x0 - x4
         * ---------------------------------------------
         */
 func plat_crash_console_init
index 99a054c8a3376ba36e5cf80db57fb7fb07144307..af3a4073b8cec38aefcfac801ac7a1f84347e249 100644 (file)
@@ -63,7 +63,7 @@ endfunc platform_is_primary_cpu
         * int plat_crash_console_init(void)
         * Function to initialize the crash console
         * without a C Runtime to print crash report.
-        * Clobber list : x0, x1, x2
+        * Clobber list : x0 - x4
         * ---------------------------------------------
         */
 func plat_crash_console_init
index a4caf5ef215b6350381db85bbce168567b1d0e0e..905c4c5fe5c7ea86a68d217050297f8fb924128e 100644 (file)
@@ -186,7 +186,7 @@ endfunc platform_mem_init
         * int plat_crash_console_init(void)
         * Function to initialize the crash console
         * without a C Runtime to print crash report.
-        * Clobber list : x0, x1, x2
+        * Clobber list : x0 - x4
         * ---------------------------------------------
         */
 func plat_crash_console_init